//
//  CZEmoticonViewController.swift
//  01.表情键盘
//
//  Created by Apple on 15/12/27.
//  Copyright © 2015年 Apple. All rights reserved.
//

import UIKit

class CZEmoticonViewController: UIViewController {
    
    // MARK: - 属性
    /// 表情要添加到的textView,控制器没有必要强引用
    weak var textView: UITextView?
    
    /// cell的重用表示
    private let ReuseIdentifier = "ReuseIdentifier"
    
    /// 表情包模型, 访问packages静态属性只会从磁盘加载一次表情模型
    private let packages = CZEmoticonPackage.packages
    
    /// 按钮起始tag
    var baseTag = 1000
    
    /// 选中的按钮
    var selectedButton: UIButton?
    
    /// 构造方法,需要传入textView
    init(textView: UITextView) {
        self.textView = textView
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        prepareUI()
        
//        print("viewDidLoad 表情键盘自定义view的frame: \(view.frame)")
    }
    
//    override func viewWillAppear(animated: Bool) {
//        super.viewWillAppear(animated)
//        print("viewWillAppear 表情键盘自定义view的frame: \(view.frame)")
//    }
    
    // 在这个方法里面控制器的view的frame才确定
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
//        print("viewDidAppear 表情键盘自定义view的frame: \(view.frame)")
        // 可以在这里面来根据collectionView的大小来设置collectionView layout的itemSize
    }
    
    // MARK: - 准备UI
    private func prepareUI() {
        // 添加子控件
        view.addSubview(collectionView)
        view.addSubview(toolBar)
        
        // 添加约束,表情键盘给其他工程使用,尽可能少的依赖第三方框架
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        toolBar.translatesAutoresizingMaskIntoConstraints = false
        
        // VFL
        // collectionView水平填充父控件
        // format: VFL语句 H: 表示水平 |父控件左边 | 父控件的右边 [] 有一个view [ view的左边 ]view的右边
        // 返回的是约束的数组
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[cv]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["cv" : collectionView]))
        
        // toolBar水平填充父控件
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[tb]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["tb" : toolBar]))
        
        // 垂直方向
        // 1.collectionView的顶部和父控件的顶部重合
        // 2.collectionView的底部和toolBar的顶部重合
        // 3.toolBar高44
        // 4.toolBar底部和父控件的底部重合
        view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[cb]-0-[tb(44)]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["cb" : collectionView, "tb": toolBar]))
        
        // 设置toolBar
        setupToolBar()
        
        // 设置collectionView
        setupCollectionView()
    }
    
    /// 设置toolBar
    private func setupToolBar() {
        var items = [UIBarButtonItem]()
        var index = 0
        for package in packages! {
            let name = package.group_name_cn
            // 创建按钮.按钮的文字可以选中和高亮
            let button = UIButton()
            button.setTitle(name, forState: UIControlState.Normal)
            button.setTitleColor(UIColor.lightGrayColor(), forState: UIControlState.Normal)
            button.setTitleColor(UIColor.darkGrayColor(), forState: UIControlState.Selected)
            button.setTitleColor(UIColor.darkGrayColor(), forState: UIControlState.Highlighted)
            button.sizeToFit()
            
            // 添加点击事件
            button.addTarget(self, action: "buttonClick:", forControlEvents: UIControlEvents.TouchUpInside)
            // tag加上起始baseTag从1000开始
            button.tag = index + baseTag
            
            // 判断如果是最近按钮,选中最近按钮
            if index == 0 {
                switchSelecteButton(button)
            }
            
            let item = UIBarButtonItem(customView: button)
            
            // 添加到数组
            items.append(item)
            
            // 添加弹簧
            items.append(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil))
            
            index++
        }
        
        // 移除最后一个弹簧
        items.removeLast()
        
        // 设置toolBar的items
        toolBar.items = items
    }
    
    /// toolbar点击事件
    func buttonClick(button: UIButton) {
        print("点击了第\(button.tag - baseTag)组")
        
        // 滚动到对应的表情包
        collectionView.scrollToItemAtIndexPath(NSIndexPath(forItem: 0, inSection: button.tag - baseTag), atScrollPosition: UICollectionViewScrollPosition.Left, animated: true)
        
        // 选中点击的按钮
        switchSelecteButton(button)
    }
    
    /**
     选中某个按钮
     
     - parameter button: 要选中的按钮
     */
    private func switchSelecteButton(button: UIButton) {
        // 1. 取消上一个选中的按钮
        selectedButton?.selected = false
        
        // 2. 选中当前点击的按钮
        button.selected = true
        
        // 3. 记录下选中的按钮
        selectedButton = button
    }
    
    /// 设置collectionView
    private func setupCollectionView() {
        // 设置背景
        collectionView.backgroundColor = UIColor(white: 0.8, alpha: 1)
        
        // 注册cell
        collectionView.registerClass(CZEmoticonCell.self, forCellWithReuseIdentifier: ReuseIdentifier)
        
        // 设置数据源
        collectionView.dataSource = self
        
        // 设置代理
        collectionView.delegate = self
    }
    
    // MARK: - 懒加载
    /// collectionView,直接创建布局赋值
    private lazy var collectionView: UICollectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: CZCollectionViewFlowLayout())
    
    /// toolBar
    private lazy var toolBar: UIToolbar = UIToolbar()
}

// 继承系统的流水布局 UICollectionViewFlowLayout, 来覆盖prepareLayout来设置layout的参数
class CZCollectionViewFlowLayout: UICollectionViewFlowLayout {
    // 覆盖父类的方法
    override func prepareLayout() {
        super.prepareLayout()
        
//        print("prepareLayout: \(collectionView?.frame)")
        // 设置layout的布局参数
        let itemWidth = collectionView!.frame.width / 7
        let itemHeight = collectionView!.frame.height / 3
        self.itemSize = CGSize(width: itemWidth, height: itemHeight)
        
        // 取消间距
        self.minimumInteritemSpacing = 0
        self.minimumLineSpacing = 0
        
        // 滚动方向
        self.scrollDirection = UICollectionViewScrollDirection.Horizontal
        
        collectionView?.pagingEnabled = true
        collectionView?.bounces = false
        collectionView?.showsHorizontalScrollIndicator = false
    }
}

// MARK: - 扩展 CZEmoticonViewController 实现 UICollectionViewDataSource
extension CZEmoticonViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    /// collectionView返回多组(一个表情包是一组)
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        // 有几个表情包就返回几组
        return packages?.count ?? 0
    }
    
    /// 每组返回多少个cell
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // 获取对应的表情包
        let package = packages![section]
        
        // 返回表情包里面表情的数量
        return package.emoticons.count
    }
    
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(ReuseIdentifier, forIndexPath: indexPath) as! CZEmoticonCell
        
//        cell.backgroundColor = UIColor.randomColor()
        
        // cell显示表情需要设置表情模型
        // 获取表情包
        let package = packages![indexPath.section]
        cell.emoticon = package.emoticons[indexPath.item]
        
        return cell
    }
    
    /// 监听collectionView停止滚动
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        let showIndexPaths = collectionView.indexPathsForVisibleItems()
//        print("判断选中的按钮: \(showIndexPaths.count), \(showIndexPaths)")
        // 1.获取collectionView正在显示的cell的indexPath
        // 因为cell的frame是小数,实际显示个数不是21个是24个,要获取当前显示哪一组,拿的indexPath不要拿最前面3个和最后面3个
        let indexPath = collectionView.indexPathsForVisibleItems()[10]
        
        // 2.可以知道显示的是哪个section
        let showSection = indexPath.section
        
        // 3.找到对应的按钮
        // viewWithTag: 通过view的tag来找到对应的view.谁来调用就先找谁,没找到就他的子控件
        // 最近这个按钮的tag是0,view默认的tag是0,会先找到toolBar,所以按钮的tag不要从0开始
        // 按钮的tag是加了bastTag,通过section来找按钮需要加上baseTag
        let button = toolBar.viewWithTag(showSection + baseTag) as! UIButton
        
        // 3.切换对应的按钮高亮
        switchSelecteButton(button)
    }
    
    // 监听collectionViewcell的点击事件, cell的点击事件会被按钮的抢走(被按钮消费了)
    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        // 获取对应的表情包
        let package = packages![indexPath.section]
        
        // 获取到对应的模型
        let emoticon = package.emoticons[indexPath.item]
        
        // 将模型的表情添加到textView里面
        textView?.insertEmoticon(emoticon)

        // 在最近表情里面点击同一个表情时,会发现添加在textView上的表情不是点击的表情,原因是因为表情模型重新排序,但是显示没有更新
        // 方法1,更新collectionView的第0组
//        collectionView.reloadSections(NSIndexSet(index: 0))
        // 方法2.点击最近里面的表情不参与排序,不需要在添加到最近表情包
        if indexPath.section != 0 {
            // 将使用的表情添加到最近表情包
            CZEmoticonPackage.addFavorateEmoticon(emoticon)
        }
    }

}